using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Dimok.Web.UI {

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>	Find. </summary>
	///
	/// <remarks>	Dimon, 12/21/2010. </remarks>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	public static class Find {

		#region Parent

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Parent control. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="parent">	The parent. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static Control ParentControl(Control parent) {
			Control uc = ParentByType(parent, typeof(UserControl)) as Control;
			return uc == null ? parent.Page : uc;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Parent by type. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="parent">	The parent. </param>
		/// <param name="types">	A variable-length parameters list containing types. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static Control ParentByType(Control parent, params Type[] types) {
			foreach(Type type in types)
				if(type.IsInstanceOfType(parent)) return parent;
			return parent.Parent == null ? null : ParentByType(parent.Parent, types);
		} 
		#endregion

		#region Column

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Columns. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="grid">	The grid. </param>
		/// <param name="name">	The name. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static DataControlField Column(object grid, string name) { return Column((GridView)grid, name); }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Columns. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="grid">	The grid. </param>
		/// <param name="name">	The name. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static DataControlField Column(GridView grid, string name) { return Column(grid.Columns, name); }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Columns. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="columns">	The columns. </param>
		/// <param name="name">			The name. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static DataControlField Column(DataControlFieldCollection columns, string name) {
			foreach (DataControlField column in columns)
				if (column.ShowHeader && column.HeaderText.ToLower() == name.ToLower()) return column;
				else if (column.SortExpression.ToLower() == name.ToLower()) return column;
			return null;
		}
		#endregion

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Sibling by identifier. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="control">	The control. </param>
		/// <param name="id">				The identifier. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static Control SiblingByID(Control control, string id) {
			if(control.Parent == null) return null;
			Control c = ControlByID(control.Parent,id);
			if(c != null) return c;
			return SiblingByID(control.Parent.Parent,id);
		}

		#region Child

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Child drop down list. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="parent">	The parent. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static DropDownList ChildDropDownList(Control parent) {
			return ChildByType(parent, typeof(DropDownList)) as DropDownList;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Child text box. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="parent">	The parent. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static TextBox ChildTextBox(Control parent) {
			return ChildByType(parent, typeof(TextBox)) as TextBox;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A Control extension method that childs. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="parent">		The parent. </param>
		/// <param name="childID">	Identifier for the child. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static Control Child(this Control parent,string childID){
			return ControlByID(parent,childID);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A Control extension method that childs. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <typeparam name="TControl">	Type of the control. </typeparam>
		/// <param name="parent">	The parent. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static TControl Child<TControl>(this Control parent) where TControl : class {
			return ChildByType(parent, typeof(TControl)) as TControl; 
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Child by type. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="parent">	The parent. </param>
		/// <param name="types">	A variable-length parameters list containing types. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static Control ChildByType(Control parent, params Type[] types) { return ChildByType(null, parent, types); }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Child by type. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="ExcludeFromSearch">	The exclude from search. </param>
		/// <param name="parent">							The parent. </param>
		/// <param name="types">							A variable-length parameters list containing types. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static Control ChildByType(Type ExcludeFromSearch, Control parent, params Type[] types) {
			foreach(Type type in types)
				if(type.IsInstanceOfType(parent)) return parent;
			if(!parent.HasControls()) return null;
			Control ret;
			foreach(Control c in parent.Controls)
				if((ExcludeFromSearch == null || !ExcludeFromSearch.IsInstanceOfType(c)) && (ret = ChildByType(c, types)) != null) return ret;
			return null;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	A Control extension method that children by type. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <typeparam name="TControl">	Type of the control. </typeparam>
		/// <param name="parent">	The parent. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static TControl [] ChildrenByType<TControl>(this Control parent)where TControl:Control {
			return ChildrenByType(parent, typeof(TControl)).Cast<TControl>().ToArray();
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Children by type. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="parent">	The parent. </param>
		/// <param name="types">	A variable-length parameters list containing types. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static List<Control> ChildrenByType(Control parent, params Type[] types) {
			List<Control> children = new List<Control>();
			foreach(Type type in types)
				if(type.IsInstanceOfType(parent)) children.Add(parent);
			if(parent.HasControls())
				foreach(Control c in parent.Controls)
					children.AddRange(ChildrenByType(c, types));
			return children;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Control by identifier. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="parent">	The parent. </param>
		/// <param name="id">			The identifier. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static Control ControlByID(Control parent, string id) {
			if((parent.ID+"").ToLower() == id.ToLower()) return parent;
			Control ctrl = parent.FindControl(id);
			if(ctrl != null) return ctrl;
			if(parent.HasControls())
				foreach(Control c in parent.Controls) {
					Control control = ControlByID(c, id);
					if(control != null) return control;
				}
			return null;
		} 
		#endregion

	}
}
